﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.UI.WebControls;
using Gma.QrCodeNet.Encoding;
using Gma.QrCodeNet.Encoding.Windows.Render;

namespace ZBJF.Warranty.Common.Common
{
    public class QRCode
    {
        public ErrorCorrectionLevel Ecl;
        public string Content;
        public QuietZoneModules QuietZones;
        public int ModuleSize;
        public BitMatrix Matrix;
        public string ContentType;

        /// <summary>
        /// Parse QueryString that define the QR code properties
        /// </summary>
        /// <param name="request">HttpRequest containing HTTP GET data</param>
        /// <returns>A QR code descriptor object</returns>
        public static QRCode Init(HttpRequest request, string content)
        {
            var cp = new QRCode();

            // Error correction level
            if (!Enum.TryParse(request.QueryString["e"], out cp.Ecl))
                cp.Ecl = ErrorCorrectionLevel.L;

            // Code content to encode
            cp.Content = content;

            // Size of the quiet zone
            if (!Enum.TryParse(request.QueryString["q"], out cp.QuietZones))
                cp.QuietZones = QuietZoneModules.Two;

            // Module size
            if (!int.TryParse(request.QueryString["s"], out cp.ModuleSize))
                cp.ModuleSize = 12;

            return cp;
        }

        /// <summary>
        /// Encode the content with desired parameters and save the generated Matrix
        /// </summary>
        /// <returns>True if the encoding succeeded, false if the content is empty or too large to fit in a QR code</returns>
        public bool TryEncode()
        {
            var encoder = new QrEncoder(Ecl);
            QrCode qr;
            if (!encoder.TryEncode(Content, out qr))
                return false;

            Matrix = qr.Matrix;
            return true;
        }

        /// <summary>
        /// Render the Matrix as a PNG image
        /// </summary>
        /// <param name="ms">MemoryStream to store the image bytes into</param>
        public void Render(MemoryStream ms)
        {
            var render = new GraphicsRenderer(new FixedModuleSize(ModuleSize, QuietZones));
            render.WriteToStream(Matrix, ImageFormat.Png, ms);
            ContentType = "image/png";
        }
    }
}
